package org.wattdepot.cli.commands;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.util.tstamp.Tstamp;

/**
 *Provides the powerStats command.
 * 
 * @author David Joel Lazaro
 */
public class PowerStatsCommand implements Command {

  /**
   * Calls the listPower method.
   * 
   * @param userInput The user input.
   * @param client The WattDepotClient
   * @return Returns the method call with the proper parameters.
   */
  public String doCommand(List<String> userInput, WattDepotClient client) {
    return powerStats(userInput, client);
  }

  /**
   * Returns the maximum, minimum, or average power generated (or consumed) by the source for the
   * day. The statistic is obtained by sampling the source at the specified minute intervals for the
   * course of the day.
   * 
   * @param commandParam The input from user.
   * @param client The WattDepotClient
   * @return Returns the generated/consumed power.
   */
  private String powerStats(List<String> commandParam, WattDepotClient client) {
    StringBuffer buff = new StringBuffer();
    SourceChecker check = new SourceChecker();
    TStampChecker stampCheck = new TStampChecker();
    if (!check.sourceChecker(commandParam.get(2), client)) {
      return "";
    }

    if (!stampCheck.checkTStamp(commandParam.get(4))) {
      return "ERROR: Timestamp error.";
    }

    try {
      XMLGregorianCalendar tstamp = Tstamp.makeTimestamp(commandParam.get(4));
      int interval = Integer.parseInt(commandParam.get(6));
      int totalDay = 1440;
      int intervalToCheck = totalDay / interval;
      double currentMaxPower = 0;
      double nextPowerGenerated = 0;
      double currentMinPower = 0;
      double sumPowerGenerated = 0;
      double averageGenerated = 0;
      double nextPowerConsumed = 0;
      double sumPowerConsumed = 0;
      double averageConsumed = 0;

      if (commandParam.get(1).equalsIgnoreCase("generated")) {
        if (commandParam.get(8).equalsIgnoreCase("max")) {
          for (int i = 0; i < intervalToCheck; i++) {
            nextPowerGenerated =
                client.getPowerGenerated(commandParam.get(2), Tstamp.incrementMinutes(tstamp,
                    interval * i));
            if (currentMaxPower < nextPowerGenerated) {
              currentMaxPower = nextPowerGenerated;
            }
          }
          System.out.println("Maximum Power Generated: " + currentMaxPower);
        }
        else if (commandParam.get(8).equalsIgnoreCase("min")) {
          currentMinPower = client.getPowerGenerated(commandParam.get(2), tstamp);
          for (int i = 0; i < intervalToCheck; i++) {
            nextPowerGenerated =
                client.getPowerGenerated(commandParam.get(2), Tstamp.incrementMinutes(tstamp,
                    interval * i));
            if (currentMinPower > nextPowerGenerated) {
              currentMinPower = nextPowerGenerated;
            }
          }
          System.out.println("Minimum Power Generated: " + currentMinPower);
        }
        else if (commandParam.get(8).equalsIgnoreCase("average")) {
          for (int i = 0; i < intervalToCheck; i++) {
            nextPowerGenerated =
                client.getPowerGenerated(commandParam.get(2), Tstamp.incrementMinutes(tstamp,
                    interval * i));
            sumPowerGenerated = sumPowerGenerated + nextPowerGenerated;
          }
          averageGenerated = sumPowerGenerated / intervalToCheck;
          System.out.println("Average Power Generated: " + averageGenerated);
        }
      }
      else if (commandParam.get(1).equalsIgnoreCase("consumed")) {
        if (commandParam.get(8).equalsIgnoreCase("max")) {
          for (int i = 0; i < intervalToCheck; i++) {
            nextPowerConsumed =
                client.getPowerConsumed(commandParam.get(2), Tstamp.incrementMinutes(tstamp,
                    interval * i));
            if (currentMaxPower < nextPowerConsumed) {
              currentMaxPower = nextPowerConsumed;
            }
          }
          System.out.println("Maximum Power Consumed: " + currentMaxPower);
        }
        else if (commandParam.get(8).equalsIgnoreCase("min")) {
          currentMinPower = client.getPowerConsumed(commandParam.get(2), tstamp);
          for (int i = 0; i < intervalToCheck; i++) {
            nextPowerConsumed =
                client.getPowerConsumed(commandParam.get(2), Tstamp.incrementMinutes(tstamp,
                    interval * i));
            if (currentMinPower > nextPowerConsumed) {
              currentMinPower = nextPowerConsumed;
            }
          }
          System.out.println("Minimum Power Consumed: " + currentMinPower);
        }
        else if (commandParam.get(8).equalsIgnoreCase("average")) {
          for (int i = 0; i < intervalToCheck; i++) {
            nextPowerConsumed =
                client.getPowerConsumed(commandParam.get(2), Tstamp.incrementMinutes(tstamp,
                    interval * i));
            sumPowerConsumed = sumPowerConsumed + nextPowerConsumed;
          }
          averageConsumed = sumPowerConsumed / intervalToCheck;
          System.out.println("Average Power Consumed: " + averageConsumed);
        }
      }

    }

    catch (NotAuthorizedException e) {
      e.printStackTrace();
    }
    catch (ResourceNotFoundException e) {
      System.out.println("Error: Requested timestamp " + commandParam.get(4) + " for the source "
          + commandParam.get(2) + " not found.");
    }
    catch (BadXmlException e) {
      e.printStackTrace();
    }
    catch (MiscClientException e) {
      e.printStackTrace();
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    return buff.toString();
  }

}